﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net;

namespace LocalCronjob
{
    public partial class Form1 : Form
    {
        private int _seconds = 0;
        private int _minutes = 0;
        private int _hours = 0;

        private bool _close = false;

        ArrayList _cronNames = new ArrayList();
        Dictionary<CronId, Cron> _crons = new Dictionary<CronId, Cron>();

        public Form1()
        {
            InitializeComponent();
        }

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void label1_Click(object sender, EventArgs e)
        {

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // try load file
            loadCrons();
        }

        private void setTime()
        {
            string sign = ":";
            if (_seconds % 2 == 0)
                sign = ".";

            string minText = _minutes.ToString();
            if (_minutes < 10)
                minText = "0" + minText;
            string timeText = String.Format("{0}{1}{2}", _hours, sign, minText);
            l_time.Text = timeText;            
        }

        private void performCronjob()
        {
            //if (_crons.ContainsKey(new CronId(_hours, _minutes, )))
            //{
                foreach (KeyValuePair<CronId, Cron> kvp in _crons)
                {
                    CronId tmp_cid = new CronId(_hours, _minutes, kvp.Value.Name);
                    if (kvp.Key.Hour  == tmp_cid.Hour && kvp.Key.Minute == tmp_cid.Minute && kvp.Key.Name == tmp_cid.Name)
                    {
                        CallCronlink(kvp.Value);
                    }
                }
            //}
        }

        private void CallCronlink(Cron c)
        {
            HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(c.Link);
            webReq.Method = "GET";
            HttpWebResponse webResp = (HttpWebResponse)webReq.GetResponse();
            rtb_logs.AppendText(String.Format("[{0}:{1}:{2}] Cron \"{3}\" performed\n", _hours,_minutes,_seconds,c.Name));
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            DateTime date = DateTime.Now;
            _hours = date.Hour;
            _minutes = date.Minute;
            _seconds = date.Second;
            setTime();

            if (_seconds == 0)
            {
                performCronjob();
            }
        }

        private void b_addNew_Click(object sender, EventArgs e)
        {
            if (tb_name.Text.Length > 0 && tb_link.Text.Length > 0 && lb_hours.SelectedItems.Count > 0 && lb_minutes.SelectedItems.Count > 0)
            {
                TextWriter tw = new StreamWriter(String.Format("{0}.ci", tb_name.Text));

                // first line hours
                // second line minutes
                // third line link
                // fourth line 0 or 1 for Paused
                string line1 = "";
                foreach (Object item in lb_hours.SelectedItems)
                {
                    line1 += item.ToString() + "|";
                }
                tw.WriteLine(line1.Substring(0, line1.Length - 1));

                string line2 = "";
                foreach (Object item in lb_minutes.SelectedItems)
                {
                    line2 += item.ToString() + "|";
                }
                tw.WriteLine(line2.Substring(0, line2.Length - 1));
                tw.WriteLine(tb_link.Text);
                tw.WriteLine("0");

                tw.Close();
                tw.Dispose();


                TextWriter tw2 = new StreamWriter("crons.cl", true);
                tw2.WriteLine(tb_name.Text);
                tw2.Close();
                tw2.Dispose();


                tb_link.Text = "";
                tb_name.Text = "";
                lb_hours.SelectedItems.Clear();
                lb_minutes.SelectedItems.Clear();

                loadCrons();
                refreshCronlist();
            }
            else
            {
                MessageBox.Show("Unzureichende Angaben!");
            }
        }

        private void refreshCronlist()
        {
            lb_crons.Items.Clear();
            foreach (string str in _cronNames)
            {
                lb_crons.Items.Add(str);
            }
        }

        private void getCronInfo()
        {

        }

        private void addLog(string text)
        {
            rtb_logs.AppendText(String.Format("{0}\n", text));
        }

        private void loadCrons()
        {
            _cronNames.Clear();
            if (File.Exists("crons.cl"))
            {
                StreamReader sr = new StreamReader("crons.cl");
                while (!sr.EndOfStream)
                {
                    string read = sr.ReadLine();
                    if (read.Length > 0)
                        _cronNames.Add(read);
                }
                sr.Close();
                sr.Dispose();
                refreshCronlist();
            }
            else
            {
                File.Create("crons.cl");
            }

            // refresh cronlist
            _crons.Clear();
            foreach(string name in _cronNames)
            {
                StreamReader sr2 = new StreamReader(String.Format("{0}.ci", name));
                
                string line1 = sr2.ReadLine();   // hours
                string line2 = sr2.ReadLine();   // minutes
                string line3 = sr2.ReadLine();   // link
                string line4 = sr2.ReadLine();   // paused
                if (line1.Length > 0 && line2.Length > 0 && line3.Length > 0 && line4.Length > 0)
                {
                    string[] hours = line1.Split('|');
                    string[] mins = line2.Split('|');
                    foreach (string h in hours)
                    {
                        foreach (string m in mins)
                        {
                            if(h.Length > 0 && m.Length > 0)
                            {
                                bool paused = true;
                                if(Int32.Parse(line4) == 0)
                                {
                                    paused = false;
                                }
                                _crons.Add(new CronId(Int32.Parse(h), Int32.Parse(m), name), new Cron(name, line3, paused));
                            }
                        }                            
                    }
                }
                sr2.Close();
                sr2.Dispose();
            }

            addLog(String.Format("{0} different crons loaded ({1} calls a day)", _cronNames.Count, _crons.Count));
        }

        private void saveCrons()
        {
            TextWriter tw = new StreamWriter("crons.cl");
            foreach (KeyValuePair<CronId, Cron> kvp in _crons)
            {
                //tw.WriteLine(String.Format("{0}|{1}|{2}|{3}", kvp.Key.X, kvp.Key.Y, kvp.Value.Name, kvp.Value.Link));
                tw.WriteLine(kvp.Value.Name);
            }
            tw.Close();
            tw.Dispose();
        }

        private void b_refresh_Click(object sender, EventArgs e)
        {
            refreshCronlist();
        }

        private void b_delete_Click(object sender, EventArgs e)
        {
            if (lb_crons.SelectedIndex >= 0)
            {
                for (int h = 0; h <= 23; h++)
                {
                    for (int min = 0; min <= 55; min += 5)
                    {
                        if (_crons.ContainsKey(new CronId(h, min,lb_crons.SelectedItem.ToString())))
                        {
                            File.Delete(String.Format("{0}.ci", lb_crons.SelectedItem));
                            _crons.Remove(new CronId(h, min, lb_crons.SelectedItem.ToString()));
                        }
                    }
                }
                lb_crons.Items.RemoveAt(lb_crons.SelectedIndex);
            }
            saveCrons();
        }

        private void showCronjobsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (showCronjobsToolStripMenuItem.Text == "Show")
            {
                this.WindowState = FormWindowState.Normal;
                showCronjobsToolStripMenuItem.Text = "Hide";
            }
            else
            {
                this.WindowState = FormWindowState.Minimized;
                showCronjobsToolStripMenuItem.Text = "Show";
            }
        }

        private void pauseAllCronsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (pauseAllCronsToolStripMenuItem.Text == "Pause")
            {
                timer.Stop();
                pauseAllCronsToolStripMenuItem.Text = "Continue";
            }
            else
            {
                timer.Start();
                pauseAllCronsToolStripMenuItem.Text = "Pause";
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing && !_close)
            {
                e.Cancel = true;
                this.WindowState = FormWindowState.Minimized;
                showCronjobsToolStripMenuItem.Text = "Show";
            }
        }

        private void closeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _close = true;
            this.Close();
        }
    }

    public struct CronId
    {
        public int Hour;
        public int Minute;
        public string Name;

        public CronId(int hour, int minute, string name)
        {
            this.Hour = hour;
            this.Minute = minute;
            this.Name = name;
        }
    }

    public struct Cron
    {
        public string Name;
        public string Link;
        public bool Paused;

        public Cron(string name, string link, bool paused)
        {
            this.Name = name;
            this.Link = link;
            this.Paused = paused;
        }
    }

}
